var mxCodecRegistry = {
    codecs: [],
    aliases: [],
    register: function(a) {
        if (a != null) {
            var b = a.getName();
            mxCodecRegistry.codecs[b] = a;
            var c = mxUtils.getFunctionName(a.template.constructor);
            c != b && mxCodecRegistry.addAlias(c, b)
        }
        return a
    },
    addAlias: function(a, b) {
        mxCodecRegistry.aliases[a] = b
    },
    getCodec: function(a) {
        var b = null;
        if (a != null) {
            var b = mxUtils.getFunctionName(a),
            c = mxCodecRegistry.aliases[b];
            c != null && (b = c);
            b = mxCodecRegistry.codecs[b];
            if (b == null) try {
                b = new mxObjectCodec(new a);
                mxCodecRegistry.register(b)
            } catch(d) {}
        }
        return b
    }
};
function mxCodec(a) {
    this.document = a || mxUtils.createXmlDocument();
    this.objects = []
}
mxCodec.prototype.document = null;
mxCodec.prototype.objects = null;
mxCodec.prototype.encodeDefaults = !1;
mxCodec.prototype.putObject = function(a, b) {
    return this.objects[a] = b
};
mxCodec.prototype.getObject = function(a) {
    var b = null;
    if (a != null) {
        b = this.objects[a];
        if (b == null) {
            b = this.lookup(a);
            if (b == null) {
                a = this.getElementById(a);
                a != null && (b = this.decode(a))
            }
        }
    }
    return b
};
mxCodec.prototype.lookup = function() {
    return null
};
mxCodec.prototype.getElementById = function(a, b) {
    return mxUtils.findNodeByAttribute(this.document.documentElement, b != null ? b: "id", a)
};
mxCodec.prototype.getId = function(a) {
    var b = null;
    if (a != null) {
        b = this.reference(a);
        if (b == null && a instanceof mxCell) {
            b = a.getId();
            if (b == null) {
                b = mxCellPath.create(a);
                b.length == 0 && (b = "root")
            }
        }
    }
    return b
};
mxCodec.prototype.reference = function() {
    return null
};
mxCodec.prototype.encode = function(a) {
    var b = null;
    if (a != null && a.constructor != null) {
        var c = mxCodecRegistry.getCodec(a.constructor);
        c != null ? b = c.encode(this, a) : mxUtils.isNode(a) ? b = mxClient.IS_IE ? a.cloneNode(true) : this.document.importNode(a, true) : mxLog.warn("mxCodec.encode: No codec for " + mxUtils.getFunctionName(a.constructor))
    }
    return b
};
mxCodec.prototype.decode = function(a, b) {
    var c = null;
    if (a != null && a.nodeType == mxConstants.NODETYPE_ELEMENT) {
        var d = null;
        try {
            d = eval(a.nodeName)
        } catch(e) {}
        try {
            var f = mxCodecRegistry.getCodec(d);
            if (f != null) c = f.decode(this, a, b);
            else {
                c = a.cloneNode(true);
                c.removeAttribute("as")
            }
        } catch(g) {
            mxLog.debug("Cannot decode " + a.nodeName + ": " + g.message)
        }
    }
    return c
};
mxCodec.prototype.encodeCell = function(a, b, c) {
    b.appendChild(this.encode(a));
    if (c == null || c) for (var c = a.getChildCount(), d = 0; d < c; d++) this.encodeCell(a.getChildAt(d), b)
};
mxCodec.prototype.isCellCodec = function(a) {
    return a != null && typeof a.isCellCodec == "function" ? a.isCellCodec() : false
};
mxCodec.prototype.decodeCell = function(a, b) {
    var b = b != null ? b: true,
    c = null;
    if (a != null && a.nodeType == mxConstants.NODETYPE_ELEMENT) {
        c = mxCodecRegistry.getCodec(a.nodeName);
        if (!this.isCellCodec(c)) for (var d = a.firstChild; d != null && !this.isCellCodec(c);) {
            c = mxCodecRegistry.getCodec(d.nodeName);
            d = d.nextSibling
        }
        this.isCellCodec(c) || (c = mxCodecRegistry.getCodec(mxCell));
        c = c.decode(this, a);
        b && this.insertIntoGraph(c)
    }
    return c
};
mxCodec.prototype.insertIntoGraph = function(a) {
    var b = a.parent,
    c = a.getTerminal(true),
    d = a.getTerminal(false);
    a.setTerminal(null, false);
    a.setTerminal(null, true);
    a.parent = null;
    b != null && b.insert(a);
    c != null && c.insertEdge(a, true);
    d != null && d.insertEdge(a, false)
};
mxCodec.prototype.setAttribute = function(a, b, c) {
    b != null && c != null && a.setAttribute(b, c)
};
function mxObjectCodec(a, b, c, d) {
    this.template = a;
    this.exclude = b != null ? b: [];
    this.idrefs = c != null ? c: [];
    this.mapping = d != null ? d: [];
    this.reverse = {};
    for (var e in this.mapping) this.reverse[this.mapping[e]] = e
}
mxObjectCodec.prototype.template = null;
mxObjectCodec.prototype.exclude = null;
mxObjectCodec.prototype.idrefs = null;
mxObjectCodec.prototype.mapping = null;
mxObjectCodec.prototype.reverse = null;
mxObjectCodec.prototype.getName = function() {
    return mxUtils.getFunctionName(this.template.constructor)
};
mxObjectCodec.prototype.cloneTemplate = function() {
    return new this.template.constructor
};
mxObjectCodec.prototype.getFieldName = function(a) {
    if (a != null) {
        var b = this.reverse[a];
        b != null && (a = b)
    }
    return a
};
mxObjectCodec.prototype.getAttributeName = function(a) {
    if (a != null) {
        var b = this.mapping[a];
        b != null && (a = b)
    }
    return a
};
mxObjectCodec.prototype.isExcluded = function(a, b) {
    return b == mxObjectIdentity.FIELD_NAME || mxUtils.indexOf(this.exclude, b) >= 0
};
mxObjectCodec.prototype.isReference = function(a, b) {
    return mxUtils.indexOf(this.idrefs, b) >= 0
};
mxObjectCodec.prototype.encode = function(a, b) {
    var c = a.document.createElement(this.getName()),
    b = this.beforeEncode(a, b, c);
    this.encodeObject(a, b, c);
    return this.afterEncode(a, b, c)
};
mxObjectCodec.prototype.encodeObject = function(a, b, c) {
    a.setAttribute(c, "id", a.getId(b));
    for (var d in b) {
        var e = d,
        f = b[e];
        if (f != null && !this.isExcluded(b, e, f, true)) {
            mxUtils.isNumeric(e) && (e = null);
            this.encodeValue(a, b, e, f, c)
        }
    }
};
mxObjectCodec.prototype.encodeValue = function(a, b, c, d, e) {
    if (d != null) {
        if (this.isReference(b, c, d, true)) {
            var f = a.getId(d);
            if (f == null) {
                mxLog.warn("mxObjectCodec.encode: No ID for " + this.getName() + "." + c + "=" + d);
                return
            }
            d = f
        }
        f = this.template[c];
        if (c == null || a.encodeDefaults || f != d) {
            c = this.getAttributeName(c);
            this.writeAttribute(a, b, c, d, e)
        }
    }
};
mxObjectCodec.prototype.writeAttribute = function(a, b, c, d, e) {
    typeof d != "object" ? this.writePrimitiveAttribute(a, b, c, d, e) : this.writeComplexAttribute(a, b, c, d, e)
};
mxObjectCodec.prototype.writePrimitiveAttribute = function(a, b, c, d, e) {
    d = this.convertValueToXml(d);
    if (c == null) {
        b = a.document.createElement("add");
        typeof d == "function" ? b.appendChild(a.document.createTextNode(d)) : a.setAttribute(b, "value", d);
        e.appendChild(b)
    } else typeof d != "function" && a.setAttribute(e, c, d)
};
mxObjectCodec.prototype.writeComplexAttribute = function(a, b, c, d, e) {
    a = a.encode(d);
    if (a != null) {
        c != null && a.setAttribute("as", c);
        e.appendChild(a)
    } else mxLog.warn("mxObjectCodec.encode: No node for " + this.getName() + "." + c + ": " + d)
};
mxObjectCodec.prototype.convertValueToXml = function(a) {
    if (typeof a.length == "undefined" && (a == true || a == false)) a = a == true ? "1": "0";
    return a
};
mxObjectCodec.prototype.convertValueFromXml = function(a) {
    mxUtils.isNumeric(a) && (a = parseFloat(a));
    return a
};
mxObjectCodec.prototype.beforeEncode = function(a, b) {
    return b
};
mxObjectCodec.prototype.afterEncode = function(a, b, c) {
    return c
};
mxObjectCodec.prototype.decode = function(a, b, c) {
    var d = b.getAttribute("id"),
    e = a.objects[d];
    if (e == null) {
        e = c || this.cloneTemplate();
        d != null && a.putObject(d, e)
    }
    b = this.beforeDecode(a, b, e);
    this.decodeNode(a, b, e);
    return this.afterDecode(a, b, e)
};
mxObjectCodec.prototype.decodeNode = function(a, b, c) {
    if (b != null) {
        this.decodeAttributes(a, b, c);
        this.decodeChildren(a, b, c)
    }
};
mxObjectCodec.prototype.decodeAttributes = function(a, b, c) {
    b = b.attributes;
    if (b != null) for (var d = 0; d < b.length; d++) this.decodeAttribute(a, b[d], c)
};
mxObjectCodec.prototype.decodeAttribute = function(a, b, c) {
    var d = b.nodeName;
    if (d != "as" && d != "id") {
        var b = this.convertValueFromXml(b.nodeValue),
        e = this.getFieldName(d);
        if (this.isReference(c, e, b, false)) {
            a = a.getObject(b);
            if (a == null) {
                mxLog.warn("mxObjectCodec.decode: No object for " + this.getName() + "." + d + "=" + b);
                return
            }
            b = a
        }
        this.isExcluded(c, d, b, false) || (c[d] = b)
    }
};
mxObjectCodec.prototype.decodeChildren = function(a, b, c) {
    for (b = b.firstChild; b != null;) {
        var d = b.nextSibling;
        b.nodeType == mxConstants.NODETYPE_ELEMENT && !this.processInclude(a, b, c) && this.decodeChild(a, b, c);
        b = d
    }
};
mxObjectCodec.prototype.decodeChild = function(a, b, c) {
    var d = this.getFieldName(b.getAttribute("as"));
    if (d == null || !this.isExcluded(c, d, b, false)) {
        var e = this.getFieldTemplate(c, d, b),
        f = null;
        if (b.nodeName == "add") {
            f = b.getAttribute("value");
            f == null && (f = mxUtils.eval(mxUtils.getTextContent(b)))
        } else f = a.decode(b, e);
        this.addObjectValue(c, d, f, e)
    }
};
mxObjectCodec.prototype.getFieldTemplate = function(a, b) {
    var c = a[b];
    c instanceof Array && c.length > 0 && (c = null);
    return c
};
mxObjectCodec.prototype.addObjectValue = function(a, b, c, d) {
    c != null && c != d && (b != null && b.length > 0 ? a[b] = c: a.push(c))
};
mxObjectCodec.prototype.processInclude = function(a, b, c) {
    if (b.nodeName == "include") {
        b = b.getAttribute("name");
        if (b != null) try {
            var d = mxUtils.load(b).getDocumentElement();
            d != null && a.decode(d, c)
        } catch(e) {}
        return true
    }
    return false
};
mxObjectCodec.prototype.beforeDecode = function(a, b) {
    return b
};
mxObjectCodec.prototype.afterDecode = function(a, b, c) {
    return c
};
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxCell, ["children", "edges", "overlays", "mxTransient"], ["parent", "source", "target"]);
    a.isCellCodec = function() {
        return true
    };
    a.isExcluded = function(a, c, d, e) {
        return mxObjectCodec.prototype.isExcluded.apply(this, arguments) || e && c == "value" && d.nodeType == mxConstants.NODETYPE_ELEMENT
    };
    a.afterEncode = function(a, c, d) {
        if (c.value != null && c.value.nodeType == mxConstants.NODETYPE_ELEMENT) {
            var e = d,
            d = mxClient.IS_IE ? c.value.cloneNode(true) : a.document.importNode(c.value, true);
            d.appendChild(e);
            a = e.getAttribute("id");
            d.setAttribute("id", a);
            e.removeAttribute("id")
        }
        return d
    };
    a.beforeDecode = function(a, c, d) {
        var e = c,
        f = this.getName();
        if (c.nodeName != f) {
            e = c.getElementsByTagName(f)[0];
            if (e != null && e.parentNode == c) {
                mxUtils.removeWhitespace(e, true);
                mxUtils.removeWhitespace(e, false);
                e.parentNode.removeChild(e)
            } else e = null;
            d.value = c.cloneNode(true);
            c = d.value.getAttribute("id");
            if (c != null) {
                d.setId(c);
                d.value.removeAttribute("id")
            }
        } else d.setId(c.getAttribute("id"));
        if (e != null) for (c = 0; c < this.idrefs.length; c++) {
            var f = this.idrefs[c],
            g = e.getAttribute(f);
            if (g != null) {
                e.removeAttribute(f);
                var h = a.objects[g] || a.lookup(g);
                if (h == null) {
                    g = a.getElementById(g);
                    g != null && (h = (mxCodecRegistry.codecs[g.nodeName] || this).decode(a, g))
                }
                d[f] = h
            }
        }
        return e
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxGraphModel);
    a.encodeObject = function(a, c, d) {
        var e = a.document.createElement("root");
        a.encodeCell(c.getRoot(), e);
        d.appendChild(e)
    };
    a.decodeChild = function(a, c, d) {
        c.nodeName == "root" ? this.decodeRoot(a, c, d) : mxObjectCodec.prototype.decodeChild.apply(this, arguments)
    };
    a.decodeRoot = function(a, c, d) {
        for (var e = null,
        c = c.firstChild; c != null;) {
            var f = a.decodeCell(c);
            f != null && f.getParent() == null && (e = f);
            c = c.nextSibling
        }
        e != null && d.setRoot(e)
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxRootChange, ["model", "previous", "root"]);
    a.afterEncode = function(a, c, d) {
        a.encodeCell(c.root, d);
        return d
    };
    a.beforeDecode = function(a, c, d) {
        if (c.firstChild != null && c.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT) {
            var c = c.cloneNode(true),
            e = c.firstChild;
            d.root = a.decodeCell(e, false);
            d = e.nextSibling;
            e.parentNode.removeChild(e);
            for (e = d; e != null;) {
                d = e.nextSibling;
                a.decodeCell(e);
                e.parentNode.removeChild(e);
                e = d
            }
        }
        return c
    };
    a.afterDecode = function(a, c, d) {
        d.previous = d.root;
        return d
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxChildChange, ["model", "child", "previousIndex"], ["parent", "previous"]);
    a.isReference = function(a, c, d, e) {
        return c == "child" && (a.previous != null || !e) ? true: mxUtils.indexOf(this.idrefs, c) >= 0
    };
    a.afterEncode = function(a, c, d) {
        this.isReference(c, "child", c.child, true) ? d.setAttribute("child", a.getId(c.child)) : a.encodeCell(c.child, d);
        return d
    };
    a.beforeDecode = function(a, c, d) {
        if (c.firstChild != null && c.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT) {
            var c = c.cloneNode(true),
            e = c.firstChild;
            d.child = a.decodeCell(e, false);
            d = e.nextSibling;
            e.parentNode.removeChild(e);
            for (e = d; e != null;) {
                d = e.nextSibling;
                if (e.nodeType == mxConstants.NODETYPE_ELEMENT) {
                    var f = e.getAttribute("id");
                    a.lookup(f) == null && a.decodeCell(e)
                }
                e.parentNode.removeChild(e);
                e = d
            }
        } else {
            e = c.getAttribute("child");
            d.child = a.getObject(e)
        }
        return c
    };
    a.afterDecode = function(a, c, d) {
        d.child.parent = d.previous;
        d.previous = d.parent;
        d.previousIndex = d.index;
        return d
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxTerminalChange, ["model", "previous"], ["cell", "terminal"]);
    a.afterDecode = function(a, c, d) {
        d.previous = d.terminal;
        return d
    };
    return a
} ());
var mxGenericChangeCodec = function(a, b) {
    var c = new mxObjectCodec(a, ["model", "previous"], ["cell"]);
    c.afterDecode = function(a, c, f) {
        if (mxUtils.isNode(f.cell)) f.cell = a.decodeCell(f.cell, false);
        f.previous = f[b];
        return f
    };
    return c
};
mxCodecRegistry.register(mxGenericChangeCodec(new mxValueChange, "value"));
mxCodecRegistry.register(mxGenericChangeCodec(new mxStyleChange, "style"));
mxCodecRegistry.register(mxGenericChangeCodec(new mxGeometryChange, "geometry"));
mxCodecRegistry.register(mxGenericChangeCodec(new mxCollapseChange, "collapsed"));
mxCodecRegistry.register(mxGenericChangeCodec(new mxVisibleChange, "visible"));
mxCodecRegistry.register(mxGenericChangeCodec(new mxCellAttributeChange, "value"));
mxCodecRegistry.register(function() {
    return new mxObjectCodec(new mxGraph, ["graphListeners", "eventListeners", "view", "container", "cellRenderer", "editor", "selection"])
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxGraphView);
    a.encode = function(a, c) {
        return this.encodeCell(a, c, c.graph.getModel().getRoot())
    };
    a.encodeCell = function(a, c, d) {
        var e = c.graph.getModel(),
        f = c.getState(d),
        g = e.getParent(d);
        if (g == null || f != null) {
            var h = e.getChildCount(d),
            k = c.graph.getCellGeometry(d),
            i = null;
            g == e.getRoot() ? i = "layer": g == null ? i = "graph": e.isEdge(d) ? i = "edge": h > 0 && k != null ? i = "group": e.isVertex(d) && (i = "vertex");
            if (i != null) {
                var l = a.document.createElement(i);
                if (c.graph.getLabel(d) != null) {
                    l.setAttribute("label", c.graph.getLabel(d));
                    c.graph.isHtmlLabel(d) && l.setAttribute("html", true)
                }
                if (g == null) {
                    var m = c.getGraphBounds();
                    if (m != null) {
                        l.setAttribute("x", Math.round(m.x));
                        l.setAttribute("y", Math.round(m.y));
                        l.setAttribute("width", Math.round(m.width));
                        l.setAttribute("height", Math.round(m.height))
                    }
                    l.setAttribute("scale", c.scale)
                } else if (f != null && k != null) {
                    for (m in f.style) {
                        g = f.style[m];
                        typeof g == "function" && typeof g == "object" && (g = mxStyleRegistry.getName(g));
                        g != null && (typeof g != "function" && typeof g != "object") && l.setAttribute(m, g)
                    }
                    g = f.absolutePoints;
                    if (g != null && g.length > 0) {
                        k = Math.round(g[0].x) + "," + Math.round(g[0].y);
                        for (m = 1; m < g.length; m++) k = k + (" " + Math.round(g[m].x) + "," + Math.round(g[m].y));
                        l.setAttribute("points", k)
                    } else {
                        l.setAttribute("x", Math.round(f.x));
                        l.setAttribute("y", Math.round(f.y));
                        l.setAttribute("width", Math.round(f.width));
                        l.setAttribute("height", Math.round(f.height))
                    }
                    m = f.absoluteOffset;
                    if (m != null) {
                        m.x != 0 && l.setAttribute("dx", Math.round(m.x));
                        m.y != 0 && l.setAttribute("dy", Math.round(m.y))
                    }
                }
                for (m = 0; m < h; m++) {
                    f = this.encodeCell(a, c, e.getChildAt(d, m));
                    f != null && l.appendChild(f)
                }
            }
        }
        return l
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxStylesheet);
    a.encode = function(a, c) {
        var d = a.document.createElement(this.getName()),
        e;
        for (e in c.styles) {
            var f = c.styles[e],
            g = a.document.createElement("add");
            if (e != null) {
                g.setAttribute("as", e);
                for (var h in f) {
                    var k = this.getStringValue(h, f[h]);
                    if (k != null) {
                        var i = a.document.createElement("add");
                        i.setAttribute("value", k);
                        i.setAttribute("as", h);
                        g.appendChild(i)
                    }
                }
                g.childNodes.length > 0 && d.appendChild(g)
            }
        }
        return d
    };
    a.getStringValue = function(a, c) {
        var d = typeof c;
        d == "function" ? c = mxStyleRegistry.getName(style[j]) : d == "object" && (c = null);
        return c
    };
    a.decode = function(a, c, d) {
        var d = d || new this.template.constructor,
        e = c.getAttribute("id");
        e != null && (a.objects[e] = d);
        for (c = c.firstChild; c != null;) {
            if (!this.processInclude(a, c, d) && c.nodeName == "add") {
                e = c.getAttribute("as");
                if (e != null) {
                    var f = c.getAttribute("extend"),
                    g = f != null ? mxUtils.clone(d.styles[f]) : null;
                    if (g == null) {
                        f != null && mxLog.warn("mxStylesheetCodec.decode: stylesheet " + f + " not found to extend");
                        g = {}
                    }
                    for (f = c.firstChild; f != null;) {
                        if (f.nodeType == mxConstants.NODETYPE_ELEMENT) {
                            var h = f.getAttribute("as");
                            if (f.nodeName == "add") {
                                var k = mxUtils.getTextContent(f),
                                i = null;
                                if (k != null && k.length > 0) i = mxUtils.eval(k);
                                else {
                                    i = f.getAttribute("value");
                                    mxUtils.isNumeric(i) && (i = parseFloat(i))
                                }
                                i != null && (g[h] = i)
                            } else f.nodeName == "remove" && delete g[h]
                        }
                        f = f.nextSibling
                    }
                    d.putCellStyle(e, g)
                }
            }
            c = c.nextSibling
        }
        return d
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxDefaultKeyHandler);
    a.encode = function() {
        return null
    };
    a.decode = function(a, c, d) {
        if (d != null) for (c = c.firstChild; c != null;) {
            if (!this.processInclude(a, c, d) && c.nodeName == "add") {
                var e = c.getAttribute("as"),
                f = c.getAttribute("action"),
                g = c.getAttribute("control");
                d.bindAction(e, f, g)
            }
            c = c.nextSibling
        }
        return d
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxDefaultToolbar);
    a.encode = function() {
        return null
    };
    a.decode = function(a, c, d) {
        if (d != null) for (var e = d.editor,
        c = c.firstChild; c != null;) {
            if (c.nodeType == mxConstants.NODETYPE_ELEMENT && !this.processInclude(a, c, d)) if (c.nodeName == "separator") d.addSeparator();
            else if (c.nodeName == "br") d.toolbar.addBreak();
            else if (c.nodeName == "hr") d.toolbar.addLine();
            else if (c.nodeName == "add") {
                var f = c.getAttribute("as"),
                f = mxResources.get(f) || f,
                g = c.getAttribute("icon"),
                h = c.getAttribute("pressedIcon"),
                k = c.getAttribute("action"),
                i = c.getAttribute("mode"),
                l = c.getAttribute("template"),
                m = c.getAttribute("toggle") != "0",
                n = mxUtils.getTextContent(c),
                o = null;
                if (k != null) o = d.addItem(f, g, k, h);
                else if (i != null) var p = mxUtils.eval(n),
                o = d.addMode(f, g, i, h, p);
                else if (l != null || n != null && n.length > 0) {
                    o = e.templates[l];
                    l = c.getAttribute("style");
                    if (o != null && l != null) {
                        o = o.clone();
                        o.setStyle(l)
                    }
                    l = null;
                    n != null && n.length > 0 && (l = mxUtils.eval(n));
                    o = d.addPrototype(f, g, o, h, l, m)
                } else {
                    h = mxUtils.getChildNodes(c);
                    if (h.length > 0) if (g == null) {
                        l = d.addActionCombo(f);
                        for (f = 0; f < h.length; f++) {
                            m = h[f];
                            if (m.nodeName == "separator") d.addOption(l, "---");
                            else if (m.nodeName == "add") {
                                g = m.getAttribute("as");
                                m = m.getAttribute("action");
                                d.addActionOption(l, g, m)
                            }
                        }
                    } else {
                        var q = null,
                        t = d.addPrototype(f, g,
                        function() {
                            var a = e.templates[q.value];
                            if (a != null) {
                                var a = a.clone(),
                                b = q.options[q.selectedIndex].cellStyle;
                                b != null && a.setStyle(b);
                                return a
                            }
                            mxLog.warn("Template " + a + " not found");
                            return null
                        },
                        null, null, m),
                        q = d.addCombo();
                        mxEvent.addListener(q, "change",
                        function() {
                            d.toolbar.selectMode(t,
                            function(a) {
                                a = mxUtils.convertPoint(e.graph.container, mxEvent.getClientX(a), mxEvent.getClientY(a));
                                return e.addVertex(null, p(), a.x, a.y)
                            });
                            d.toolbar.noReset = false
                        });
                        for (f = 0; f < h.length; f++) {
                            m = h[f];
                            if (m.nodeName == "separator") d.addOption(q, "---");
                            else if (m.nodeName == "add") {
                                g = m.getAttribute("as");
                                n = m.getAttribute("template");
                                d.addOption(q, g, n || l).cellStyle = m.getAttribute("style")
                            }
                        }
                    }
                }
                if (o != null) {
                    l = c.getAttribute("id");
                    l != null && l.length > 0 && o.setAttribute("id", l)
                }
            }
            c = c.nextSibling
        }
        return d
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxDefaultPopupMenu);
    a.encode = function() {
        return null
    };
    a.decode = function(a, c, d) {
        var e = c.getElementsByTagName("include")[0];
        if (e != null) this.processInclude(a, e, d);
        else if (d != null) d.config = c;
        return d
    };
    return a
} ());
mxCodecRegistry.register(function() {
    var a = new mxObjectCodec(new mxEditor, ["modified", "lastSnapshot", "ignoredChanges", "undoManager", "graphContainer", "toolbarContainer"]);
    a.afterDecode = function(a, c, d) {
        a = c.getAttribute("defaultEdge");
        if (a != null) {
            c.removeAttribute("defaultEdge");
            d.defaultEdge = d.templates[a]
        }
        a = c.getAttribute("defaultGroup");
        if (a != null) {
            c.removeAttribute("defaultGroup");
            d.defaultGroup = d.templates[a]
        }
        return d
    };
    a.decodeChild = function(a, c, d) {
        if (c.nodeName == "Array") {
            if (c.getAttribute("as") == "templates") {
                this.decodeTemplates(a, c, d);
                return
            }
        } else if (c.nodeName == "ui") {
            this.decodeUi(a, c, d);
            return
        }
        mxObjectCodec.prototype.decodeChild.apply(this, arguments)
    };
    a.decodeUi = function(a, c, d) {
        for (a = c.firstChild; a != null;) {
            if (a.nodeName == "add") {
                var c = a.getAttribute("as"),
                e = a.getAttribute("element"),
                f = a.getAttribute("style"),
                g = null;
                if (e != null) {
                    g = document.getElementById(e);
                    if (g != null && f != null) g.style.cssText = g.style.cssText + (";" + f)
                } else {
                    var e = parseInt(a.getAttribute("x")),
                    h = parseInt(a.getAttribute("y")),
                    k = a.getAttribute("width"),
                    i = a.getAttribute("height"),
                    g = document.createElement("div");
                    g.style.cssText = f; (new mxWindow(mxResources.get(c) || c, g, e, h, k, i, false, true)).setVisible(true)
                }
                c == "graph" ? d.setGraphContainer(g) : c == "toolbar" ? d.setToolbarContainer(g) : c == "title" ? d.setTitleContainer(g) : c == "status" ? d.setStatusContainer(g) : c == "map" && d.setMapContainer(g)
            } else a.nodeName == "resource" ? mxResources.add(a.getAttribute("basename")) : a.nodeName == "stylesheet" && mxClient.link("stylesheet", a.getAttribute("name"));
            a = a.nextSibling
        }
    };
    a.decodeTemplates = function(a, c, d) {
        if (d.templates == null) d.templates = [];
        for (var c = mxUtils.getChildNodes(c), e = 0; e < c.length; e++) {
            for (var f = c[e].getAttribute("as"), g = c[e].firstChild; g != null && g.nodeType != 1;) g = g.nextSibling;
            g != null && (d.templates[f] = a.decodeCell(g))
        }
    };
    return a
} ());